/*
 * IndiceArbolB.cpp
 *
 *  Created on: 15/10/2009
 *      Author: andres
 */

//#define CANT_CLAVES 5;

#include "IndiceArbolB.h"

IndiceArbolB::IndiceArbolB(PrimaryKey *primaryKey) throw(IndexException) : EstrategiaIndice( primaryKey)
{
	raiz=new NodoArbolB(5);
}

IndiceArbolB::IndiceArbolB(PrimaryKey *PrimaryKey, SecondaryKey *secondaryKey, EstrategiaIndice *indicePrimario) throw(IndexException) :EstrategiaIndice( PrimaryKey, secondaryKey, indicePrimario)
{
	raiz=new NodoArbolB(5);
}



void IndiceArbolB::Cargar(char *datoSerializadoACargar, unsigned int id) throw(IndexException)
{
	if( raiz->nodos.size() >= 5)
	{
		//cuando se desborda la raiz se esta por duplicar le agrego otra raiz
		NodoArbolB* aux=new NodoArbolB(5);
		aux->nodos.push_back(raiz);
		Clave* clave;
		raiz->MayorClave(clave);
		aux->claves.push_back(clave);
		raiz=aux;
	}
	raiz->Ingresar(CargarInformacion(datoSerializadoACargar, id));

}



void IndiceArbolB::Eliminar(char *DatoSerializadoAEliminar)
{
	raiz->Quitar(CargarInformacion(DatoSerializadoAEliminar, 0));
}



std::vector<unsigned int> IndiceArbolB::Buscar(std::string claveABuscar)
{
	Clave* clave;
	char* buscar;
	int tamanio;
	if(this->EsIndicePrimario())
	{
		tamanio=claveABuscar.size()<(unsigned int)this->primaryKey->GetTamanio()? claveABuscar.size():this->primaryKey->GetTamanio();
		clave= new Clave(this->primaryKey->GetTamanio());
		buscar=(char*)malloc(primaryKey->GetTamanio());
		memset(buscar,0,primaryKey->GetTamanio());
		memcpy(buscar,claveABuscar.c_str(),tamanio);
	}
	else
	{
		tamanio=claveABuscar.size()<(unsigned int)this->secondaryKey->GetTamanio()? claveABuscar.size():this->secondaryKey->GetTamanio();
		clave= new Clave(this->secondaryKey->GetTamanio());
		buscar=(char*)malloc(this->secondaryKey->GetTamanio());
		memset(buscar,0,this->secondaryKey->GetTamanio());
		memcpy(buscar,claveABuscar.c_str(),tamanio);
	}



	clave->Cargar(buscar);
	vector<Informacion*> info=raiz->Buscar(clave);

	vector<unsigned int> claves;
	if(this->EsIndicePrimario())
		for(int i=0; (unsigned int)i<info.size(); i++)
		{
			claves.push_back(info[i]->GetID());
		}
	else
	{
		for(int i=0; (unsigned int)i<info.size(); i++)
		{
			std::string nombre(info[i]->GetPrimaryKey());
			claves.push_back(this->indicePrimario->Buscar(nombre)[0]);
		}
	}

	return claves;

}



void IndiceArbolB::Modificar(char *DatoSerializadoSinModificar, char *DatoSerializadoModificado, unsigned int idModificado)
{
	Eliminar(DatoSerializadoSinModificar);
	Cargar(DatoSerializadoModificado, idModificado);
}





IndiceArbolB::~IndiceArbolB()
{
	delete raiz;
}



Informacion *IndiceArbolB::CargarInformacion(char *datoSerializadoACargar, unsigned int id)
{
	Informacion* informacion;

	if(this->EsIndicePrimario())
	{
		informacion= new Informacion(this->primaryKey->GetTamanio(),4);
	}
	else
	{
		informacion= new Informacion(this->secondaryKey->GetTamanio(),this->primaryKey->GetTamanio());
	}

	DatoIndice dato(this->secondaryKey,this->primaryKey);
	informacion->Cargar(dato.GetDato(datoSerializadoACargar, id));

	return informacion;

}





